/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package me.tomato3017.plugins.epicmusic;

import java.util.HashMap;
import me.tomato3017.plugins.epicmusic.audio.AmbientMusicData;
import me.tomato3017.plugins.epicmusic.region.RegionData;
import me.tomato3017.plugins.epicmusic.thread.PlayerMusicThread;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerListener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.getspout.spoutapi.player.SpoutPlayer;

/**
 *
 * @author Anthony Kirksey <Anthony.Kirksey@gmail.com>
 */
public class EpicMusicPlayerListener extends PlayerListener{
    EpicMusic plugin;

    private HashMap<Player, LastPlayed> locationList;
    
    public EpicMusicPlayerListener(EpicMusic plugin) {
        this.plugin = plugin;
        locationList = new HashMap<Player, LastPlayed>();
    }

    @Override
    public void onPlayerQuit(PlayerQuitEvent event) {
        EpicMusic.getThreadManager().removePlayerThread(event.getPlayer());
        
        if(locationList.containsKey(event.getPlayer()))
            locationList.remove(event.getPlayer());
    }

    @Override
    public void onPlayerTeleport(PlayerTeleportEvent event) {
        PlayerMusicThread pThread = EpicMusic.getThreadManager().getPlayerThread(event.getPlayer());
        
        if(pThread != null){
            Location pLocation = event.getTo();
            RegionData rData = EpicMusic.getRegionManager().GetRegion(pLocation);
            
            //Check to see if the region is different then the threads current region
            //Update if it isn't
            if(!rData.getRegionName().equals(pThread.getCurrentRegion())){
                if(EpicMusic.isDEBUG()){
                    EpicMusic.debugLog("Player " + event.getPlayer().getDisplayName() + " changed to:" + rData.getRegionName(), 2);
                }
                pThread.setNextRegion(rData.getRegionName());
                pThread.updateThread();
            }
        }
    }

    @Override
    public void onPlayerMove(PlayerMoveEvent event) {
        Player player = event.getPlayer();
        SpoutPlayer sp = (SpoutPlayer) player;
        
        if(sp.isSpoutCraftEnabled()){
            LastPlayed lastPlayed;
            Location loc = event.getPlayer().getLocation();
            RegionData rData = null;
            
            int dist = getDistance(player);
            
            
            if(dist < 0){
                lastPlayed = new LastPlayed(loc, player);
                locationList.put(player, lastPlayed);
            }
            
            lastPlayed = locationList.get(player);
            //Only play a new sound effect if we're a sufficient distance from the last one
            if((dist > lastPlayed.getLastDistance() + 30) || dist < 0){
                int stoneCount = getStoneCount(player);
                
                if(rData == null){
                    rData = EpicMusic.getRegionManager().GetRegion(loc);
                }
                
                if(stoneCount < 7){
                    AmbientMusicData aMusic = rData.getAmbientMusic();
                    if(aMusic != null){
                        lastPlayed.setLastDistance(rData.getSoundEffectDistance());
                        lastPlayed.setLoc(loc);
                        locationList.put(player, lastPlayed);
                            
                        EpicMusic.getAudioManager().playAmbient(aMusic, player, rData.getSoundEffectDistanceSQRT() * 2);
                    }
                    else{
                        lastPlayed.setLastDistance(EpicMusic.getDefaultSoundEffectDistance());
                        lastPlayed.setLoc(loc);
                        locationList.put(player, lastPlayed);
                    }
                }
                else if(stoneCount > 15){
                    AmbientMusicData aMusic = EpicMusic.getRegionManager().getUndergroundMusic(rData);
                    
                    lastPlayed.setLastDistance(rData.getSoundEffectDistance());
                    lastPlayed.setLoc(loc);
                    locationList.put(player, lastPlayed);
                    EpicMusic.getAudioManager().playAmbient(aMusic, player, rData.getSoundEffectDistanceSQRT() * 2);
                }
            }
        }
    }

        public int getDistance(Player player)
    {
		if(locationList.containsKey(player))
		{
			Location pos = locationList.get(player).getLoc();
			Integer listX = (int) pos.getX();
                        Integer listY = (int) pos.getY();
			Integer listZ = (int) pos.getZ();
			Location loc = player.getLocation();
			Integer currentX = (int) loc.getX();
                        Integer currentY = (int) loc.getY();
			Integer currentZ = (int) loc.getZ();
                        
                        //Actually faster then using the vector distance^2 function
                        Integer distance = (currentX - listX)*(currentX - listX)+
                                           (currentY - listY)*(currentY - listY)+
                                           (currentZ - listZ)*(currentZ - listZ);
			return distance;
		}
		else
		{
			return -1;
		}
    }
    //returns the distance from the previous point
//    public int getDistance(Player player)
//    {
//		if(locationList.containsKey(player))
//		{
//			Location pos = locationList.get(player).getLoc();
//			Integer listX = (int) pos.getX();
//			Integer listZ = (int) pos.getZ();
//			Location loc = player.getLocation();
//			Integer currentX = (int) loc.getX();
//			Integer currentZ = (int) loc.getZ();
//			Integer diffX = currentX - listX;
//			Integer diffZ = currentZ - listZ;
//			if(diffX < 0)diffX = -diffX;
//			if(diffZ < 0)diffZ = -diffZ;
//			Integer distance = (diffX + diffZ)/2;
//			return distance;
//		}
//		else
//		{
//			return -1;
//		}
//    }
    
    private class LastPlayed{
        private Location loc;
        private Player player;
        private int lastDistance;

        public LastPlayed(Location loc, Player player) {
            this.loc = loc;
            this.player = player;
            this.lastDistance = EpicMusic.getDefaultSoundEffectDistance();
        }

        public Location getLoc() {
            return loc;
        }

        public void setLoc(Location loc) {
            this.loc = loc;
        }

        public Player getPlayer() {
            return player;
        }

        public void setPlayer(Player player) {
            this.player = player;
        }

        public int getLastDistance() {
            return lastDistance;
        }

        public void setLastDistance(int lastDistance) {
            this.lastDistance = lastDistance;
        }
        
        
    }
    
    private int getStoneCount(Player player){
        int stoneCount = 0;
        World world = player.getWorld();
        Location loc = player.getLocation();
        int x = (int) loc.getX();
        int z = (int) loc.getY();
        
        Integer index = 0;
        for(index = (int) loc.getY(); index < 127; index++){
            Integer ID = world.getBlockAt(loc.getBlockX(),index,loc.getBlockZ()).getTypeId();
            
            if(ID > 0 && ID < 12 )
            {
                stoneCount++;				
            }
        }
        
        return stoneCount;
    }
    
    
}
